﻿using Kimd.Common;
using Kimd.Communication;
using Kimd.Machine;
using Kimd.Motion;
using log4net;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SQLite;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Kimd.Machine
{
    public partial class FormStartUp : Form
    {
        private string _configName;
        private List<string> _showInfos;
        private List<string> _showDoneInfos;
        public List<string> startUpInfo { get; set; }
        public FormStartUp(string configName)
        {
            InitializeComponent();
            startUpInfo = new List<string>();
            _showInfos = new List<string>();
            _showDoneInfos = new List<string>();
            this._configName = configName;
        }

        private async void FormStartUp_Load(object sender, EventArgs e)
        {
            //Task startUpTask = new Task(new Action(startUp));
            //startUpTask.Start();
            await Task.Run(() => { startUp(); });
            this.DialogResult = DialogResult.OK;
            this.Close();
        }
        /// <summary>
        /// 设置窗体的Region
        /// </summary>
        public void SetWindowRegion()
        {
            GraphicsPath FormPath;
            Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);
            FormPath = GetRoundedRectPath(rect, 50);
            this.Region = new Region(FormPath);

        }
        /// <summary>
        /// 绘制圆角路径
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="radius"></param>
        /// <returns></returns>
        private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
        {
            int diameter = radius;
            Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
            GraphicsPath path = new GraphicsPath();

            // 左上角
            path.AddArc(arcRect, 180, 90);

            // 右上角
            arcRect.X = rect.Right - diameter;
            path.AddArc(arcRect, 270, 90);

            // 右下角
            arcRect.Y = rect.Bottom - diameter;
            path.AddArc(arcRect, 0, 90);

            // 左下角
            arcRect.X = rect.Left;
            path.AddArc(arcRect, 90, 90);
            path.CloseFigure();//闭合曲线
            return path;
        }

        private void pB_Background_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            Image image = Properties.Resources.logo;
            g.DrawImage(image, new Rectangle(20, 6, 200, 70));
            for (int i = 0; i < _showInfos.Count; i++)
            {
                g.DrawString(_showInfos[i], new Font("微软雅黑", 13, FontStyle.Regular), new SolidBrush(Color.FromArgb(200, Color.White)), 100, 400 + 40 * i);
            }
            for (int i = 0; i < _showDoneInfos.Count; i++)
            {
                g.DrawString(_showDoneInfos[i], new Font("微软雅黑", 13, FontStyle.Regular), new SolidBrush(Color.FromArgb(200, Color.White)), 280, 400 + 40 * i);
            }
        }
        private void addDoneInfo(string message)
        {
            _showDoneInfos.Add(message);
            this.BeginInvoke(new Action(() =>
            {
                pB_Background.Refresh();
            }));
        }
        private void addInfo(string message)
        {
            _showInfos.Add(message);
            this.BeginInvoke(new Action(() =>
            {
                pB_Background.Refresh();
            }));
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, message, "Main", 0, "系统"));
        }
        private void startUp()
        {
            #region 加载运动
            addInfo("加载运动控制硬件...");
            System.Threading.Thread.Sleep(500);
            if (false)
            {
                #region card
                SingletonProvider<MachineResource>.Instance.MachineCard = new SerializableDictionary<string, ControlCard>();
                ControlCard card = new ControlCard(0, "DMCEtherCard", "card1", "");
                SingletonProvider<MachineResource>.Instance.MachineCard.Add(card.Description, card);
                #endregion

                #region axis
                SingletonProvider<MachineResource>.Instance.MachineAxis = new SerializableDictionary<string, Axis>();
                Axis x = new Axis("card1", "Axis0", false, "X轴", "四轴验证平台");
                SingletonProvider<MachineResource>.Instance.AddAxis(x.Description, x);
                Axis y = new Axis("card1", "Axis1", false, "Y轴", "四轴验证平台");
                SingletonProvider<MachineResource>.Instance.AddAxis(y.Description, y);
                Axis z = new Axis("card1", "Axis2", false, "Z轴", "四轴验证平台");
                SingletonProvider<MachineResource>.Instance.AddAxis(z.Description, z);
                Axis r = new Axis("card1", "Axis3", false, "R轴", "四轴验证平台");
                SingletonProvider<MachineResource>.Instance.AddAxis(r.Description, r);
                #endregion

                #region Sensor
                SingletonProvider<MachineResource>.Instance.MachineSensor = new SerializableDictionary<string, Sensor>();
                Sensor nozzleVacSense1 = new Sensor("吸嘴1真空感应", "card1", "1_DIO8_IN0", true, "四轴验证平台");
                SingletonProvider<MachineResource>.Instance.AddSensor(nozzleVacSense1.Description, nozzleVacSense1);
                Sensor nozzleVacSense2 = new Sensor("吸嘴2真空感应", "card1", "1_DIO8_IN1", true, "四轴验证平台");
                SingletonProvider<MachineResource>.Instance.AddSensor(nozzleVacSense2.Description, nozzleVacSense2);
                #endregion

                #region Cylinder
                SingletonProvider<MachineResource>.Instance.MachineCylinder = new SerializableDictionary<string, Cylinder>();
                Cylinder nozzleVac1 = new Cylinder("吸嘴1真空", "card1", "1_DIO8_OUT0", "四轴验证平台");
                SingletonProvider<MachineResource>.Instance.AddCylinder(nozzleVac1.Description, nozzleVac1);
                Cylinder nozzleVac2 = new Cylinder("吸嘴2真空", "card1", "1_DIO8_OUT1", "四轴验证平台");
                SingletonProvider<MachineResource>.Instance.AddCylinder(nozzleVac2.Description, nozzleVac2);
                #endregion

                XmlSerializerHelper<MachineResource>.SerializeToFile(SingletonProvider<MachineResource>.Instance, PathHelper.GetConfigPath("Machine") + "Machine.xml");
            }
            else
            {
                SingletonProvider<MachineResource>.Instance = XmlSerializerHelper<MachineResource>.DeserializeFromFile(PathHelper.GetConfigPath("Machine") + _configName);
                MotionFactory.Instance.InitializeMotion(SingletonProvider<MachineResource>.Instance);
                MotionFactory.Instance.InitializeMotion2(SingletonProvider<MachineResource>.Instance);
                MotionFactory.Instance.InitializeLimit(SingletonProvider<MachineResource>.Instance);
                MotionFactory.Instance.InitializeTray(SingletonProvider<MachineResource>.Instance);
                foreach (var card in SingletonProvider<MachineResource>.Instance.MachineCard.Values)
                {
                    card.Open();
                }
                //PLCOperator plc = new PLCOperator("Inovance", "AM");
                //plc.IpAddress = "192.168.0.11";
                //plc.Port = 502;
                //MachineResource.Instance.MachinePLC.Add("轨道PLC", plc);
                MotionFactory.Instance.InitializePLC(SingletonProvider<MachineResource>.Instance);
                foreach (var item in MachineResource.Instance.MachinePLC.Values)
                {
                    if (item.IsInitConnect)
                    {
                        item.Connect();
                        if (!item.IsOpen)
                            startUpInfo.Add($"{item.Name}连接失败!");
                    }
                }

                //Pdo pdo = new Pdo("card1", 2, 0, "DD控制地址", "转盘模组");
                //MachineResource.Instance.MachinePdo.Add("DD控制地址", pdo);
                //pdo = new Pdo("card1", 2, 2, "DD位置地址1", "转盘模组");
                //MachineResource.Instance.MachinePdo.Add("DD位置地址1", pdo);
                //pdo = new Pdo("card1", 2, 4, "DD位置地址2", "转盘模组");
                //MachineResource.Instance.MachinePdo.Add("DD位置地址2", pdo);
                //TCPClient visionClient = new TCPClient("192.168.201.19", "8234", "Vision");
                //MachineResource.Instance.MachineTcpClient.Add(visionClient.Name, visionClient);

                //InovancePLCOperator ipo = new InovancePLCOperator();
                //PLCOperator plc = new PLCOperator("Inovance", "AM");
                //plc.SetOperator(ipo);
                //plc.IpAddress = "192.168.201.19";
                //plc.Port = 502;
                //plc.Name = "轨道PLC";

                //TCPServer robotServer = new TCPServer();
                //robotServer.IP = "192.168.201.19";
                //robotServer.Port = 9000;
                //robotServer.Name = "机械手";
                //MachineResource.Instance.MachineTcpServer.Add(robotServer.Name, robotServer);

                //MachineResource.Instance.MachinePLC.Add(plc.Name, plc);
                //MachineResource.Instance.Save();

                //TCPClient testClient = new TCPClient("192.168.0.10", "9000", "测试站左1");
                //MachineResource.Instance.MachineTcpClient.Add(testClient.Name, testClient);
                //TCPClient testClient2 = new TCPClient("192.168.0.10", "9001", "测试站左2");
                //MachineResource.Instance.MachineTcpClient.Add(testClient2.Name, testClient2);
                //TCPClient testClient3 = new TCPClient("192.168.0.11", "9000", "测试站右1");
                //MachineResource.Instance.MachineTcpClient.Add(testClient3.Name, testClient3);
                //TCPClient testClient4 = new TCPClient("192.168.0.11", "9001", "测试站右2");
                //MachineResource.Instance.MachineTcpClient.Add(testClient4.Name, testClient4);

                //TCPClient visionClient = new TCPClient("192.168.0.123", "8234", "视觉");
                //MachineResource.Instance.MachineTcpClient.Add(visionClient.Name, visionClient);
                //TCPClient robotStatus = new TCPClient("192.168.0.123", "8234", "机械手状态");
                //MachineResource.Instance.MachineTcpClient.Add(robotStatus.Name, robotStatus);
                //MachineResource.Instance.Save();
                //foreach (var item in MachineResource.Instance.MachineTcpClient.Values)
                //{
                //    if(item.IsInitConnect)
                //    {
                //        item.Connect();
                //        if (!item.IsOpenFlag)
                //            startUpInfo.Add($"{item.Name}连接失败!");
                //    }
                //}

                //if (MachineResource.Instance.MachineTcpServer != null && MachineResource.Instance.MachineTcpServer.ContainsKey("机械手"))
                //    MachineResource.Instance.MachineTcpServer["机械手"].Start();

                //TCPServer tCPServer = new TCPServer("192.168.0.10", "23", "扫码枪");
                //MachineResource.Instance.MachineTcpServer.Add("扫码枪", tCPServer);
                //MachineResource.Instance.Save();
            }

            SingletonProvider<MachineResource>.Instance.StartMonitor();
            addDoneInfo("完成!");
            #endregion

            #region 加载通信
            addInfo("加载通信端口...");
            System.Threading.Thread.Sleep(500);
            if (SingletonProvider<MachineResource>.Instance.MachineTcpClient != null)
            {
                foreach (KeyValuePair<string, TCPClient> tcpClient in SingletonProvider<MachineResource>.Instance.MachineTcpClient)
                {
                    if (tcpClient.Value.IsInitConnect)
                    {
                        if (!tcpClient.Value.Connect())
                        {
                            startUpInfo.Add($"TcpClient通信[{tcpClient.Key}]连接失败");
                            continue;
                        }
                    }
                }
            }
            if (SingletonProvider<MachineResource>.Instance.MachineModbusTcp != null)
            {
                //foreach (KeyValuePair<string, ModbusTcp> modbusClient in SingletonProvider<MachineResource>.Instance.MachineModbusTcp)
                //{
                //    if (!modbusClient.Value.Connect())
                //    {
                //        startUpInfo.Add($"ModbusTcp通信[{modbusClient.Key}]连接失败");
                //        continue;
                //    }
                //}
            }
            if (SingletonProvider<MachineResource>.Instance.MachineSerialPort != null)
            {
                //foreach (KeyValuePair<string, SerialPortHelper> serialPorts in SingletonProvider<MachineResource>.Instance.MachineSerialPort)
                //{
                //    if (!serialPorts.Value.Open())
                //    {
                //        startUpInfo.Add($"SerialPort通信[{serialPorts.Key}]连接失败");
                //        continue;
                //    }
                //}
            }
            if (SingletonProvider<MachineResource>.Instance.MachineTcpServer != null)
            {
                //foreach (KeyValuePair<string, TCPServer> tcpServers in SingletonProvider<MachineResource>.Instance.MachineTcpServer)
                //{
                //    if (!tcpServers.Value.Start())
                //    {
                //        startUpInfo.Add($"TCPServer通信[{tcpServers.Key}]启动服务器失败");
                //        continue;
                //    }
                //}
            }
            addDoneInfo("完成!");
            //System.Threading.Thread.Sleep(500);
            #endregion

            //MachineResource.Instance.MachineCoordinates.Add("YZ1", new Coordinate2D(MachineResource.Instance.MachineCard["card1"],
            //                                                                        0,
            //                                                                        MachineResource.Instance.MachineAxis["测试移载Y1轴"],
            //                                                                        MachineResource.Instance.MachineAxis["测试移载Z1轴"],
            //                                                                        "YZ1",
            //                                                                        "测试移载"));
            //MachineResource.Instance.MachineCoordinates.Add("YZ2", new Coordinate2D(MachineResource.Instance.MachineCard["card1"],
            //                                                                        1,
            //                                                                        MachineResource.Instance.MachineAxis["测试移载Y2轴"],
            //                                                                        MachineResource.Instance.MachineAxis["测试移载Z2轴"],
            //                                                                        "YZ2",
            //                                                                        "测试移载"));
        }
        private void FormStartUp_Resize(object sender, EventArgs e)
        {
            SetWindowRegion();
        }

        private void LoadConfigFile()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Title = "选择产品配置";
            openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\" +
                Path.GetFileName(Application.ExecutablePath).Split('.')[0] + "\\Machine\\";
        reGetConfig:
            openFileDialog.ShowDialog();
            while (openFileDialog.FileName == null || openFileDialog.FileName.ToString() == string.Empty)
            {
                Thread.Sleep(20);
            }
            if (!openFileDialog.FileName.EndsWith("Machine.xml") && !openFileDialog.FileName.EndsWith("MachineThick.xml"))
            {
                goto reGetConfig;
            }
            else
            {
                string[] selectedConfig = openFileDialog.FileName.ToString().Split('\\', '\\');
                _configName = selectedConfig[selectedConfig.Length - 1];
            }
        }
    }
}
